import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
import { Scene } from "@babylonjs/core/scene";
import { Utils } from "../../tool/utils";

/**
 * 锚点类型
 * @param CENTER 中心
 * @param CENTER_TOP 中上
 * @param LEFT_TOP 左上
 * @param RIGHT_TOP 右上
 * @param CENTER_BOTTOM 中下
 * @param LEFT_BOTTOM 左下
 * @param RIGHT_BOTTOM 右下
 * @param LEFT_CENTER 左中
 * @param RIGHT_CENTER 右中
 */
enum ANCHOR {
    CENTER, CENTER_TOP, LEFT_TOP, RIGHT_TOP, CENTER_BOTTOM, LEFT_BOTTOM, RIGHT_BOTTOM, LEFT_CENTER, RIGHT_CENTER
}

/**
 * 基础控件参数对象
 * @param key 键名
 * @param left 左侧位置
 * @param top 上侧位置
 * @param depth z向偏移
 * @param display 是否显示
 * @param isEnabled 是否可用
 * @param anchor 锚点
 * @param renderingGroupId 渲染顺序值
 */
interface IAbstractBaseOptions {
    key?: string,
    left?: number,
    top?: number,
    depth?: number,
    display?: boolean,
    isEnabled?: boolean,
    anchor?: ANCHOR,
    renderingGroupId?: number,
    enabledStyle?: { (enabled: boolean, scope: AbstractBase): void },
}


/**
 * 基础控件抽象类
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 */
abstract class AbstractBase {

    protected options: IAbstractBaseOptions;
    protected scene: Scene;

    public readonly id = Utils.id;
    public readonly name: string;

    public avoidEventHandle: boolean = false;

    /**
     * 控件容器
     */
    public container!: TransformNode;

    constructor(name: string, scene: Scene, options?: IAbstractBaseOptions) {
        this.name = name;
        this.scene = scene;
        this.options = options || {};
        this.options.key = this.options.key || name;
        this.options.enabledStyle = this.options.enabledStyle || undefined;
    }

    public get key(): string {
        return this.options.key!;
    }

    /**
     * 自定义启用与禁用样式
     */
    public get enabledStyle(): { (enabled: boolean, scope: AbstractBase): void } | undefined {
        return this.options.enabledStyle;
    }

    public set enabledStyle(func: { (enabled: boolean, scope: AbstractBase): void } | undefined) {
        this.options.enabledStyle = func;
    }

    /**
     * 是否是纯ui控件
     */
    public abstract get isControl(): boolean;

    /**
     * 设置是否可用
     */
    public abstract set isEnabled(enabled: boolean);

    /**
     * 获取是否可用
     */
    public abstract get isEnabled(): boolean;

    /**
     * 设置是否显示
     */
    public abstract set display(enabled: boolean);

    /**
     * 获取是否显示
     */
    public abstract get display(): boolean;

    /**
     * 设置渲染顺序值
     */
    public abstract set renderingGroupId(id: number);

    /**
     * 获取渲染顺序值
     */
    public abstract get renderingGroupId(): number;

    /**
     * 设置左侧位置
     */
    public abstract set left(left: number);

    /**
     * 获取左侧位置
     */
    public abstract get left(): number;

    /**
     * 设置上侧位置
     */
    public abstract set top(top: number);

    /**
     * 获取上侧位置
     */
    public abstract get top(): number;

    /**
     * 设置z向偏移
     */
    public abstract set depth(depth: number);

    /**
     * 获取z向偏移
     */
    public abstract get depth(): number;

    public dispose(): void {
        this.container.dispose(false);
    }

    /**
     * 初始化（容器，原始控件，行为等）
     * @param name 名称
     * @param scene 所在场景
     * @param options 参数对象
     */
    protected abstract initialize(name: string, scene: Scene, options: IAbstractBaseOptions): void;

}


export { AbstractBase, ANCHOR };
export type { IAbstractBaseOptions };